﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraTabbedMdi;
using ProgNetComponentsDx.Language;
using System.Xml;
using System.IO;
using ProgNetComponentsDx.Layout;
using System.ComponentModel;
using System.Drawing;

namespace System
{
    public static class DxFormExt
    {
        public class PNXtraMessageBoxForm : XtraMessageBoxForm
        {
            private Dictionary<DialogResult, string> _ButtonsText = new Dictionary<DialogResult, string>();
            public Dictionary<DialogResult, string> ButtonsText
            {
                get { return _ButtonsText; }
            }
            protected override string GetButtonText(DialogResult target)
            {
                if (ButtonsText.ContainsKey(target))
                    return ButtonsText[target];
                return base.GetButtonText(target);
            }
        }

        public class DialogResultText
        {
            public DialogResultText(DialogResult dlg, string text)
            {
                DialogResult = dlg;
                Text = text;
            }
            public DialogResult DialogResult
            {
                get;
                set;
            }
            public string Text
            {
                get;
                set;
            }
        }

        public static DialogResultText[] GetDialogResultText(DialogResult dlg, string txt)
        {
            return new DialogResultText[] { new DialogResultText(dlg, txt) };
        }
        public static DialogResultText[] GetDialogResultText(DialogResult dlg1, string txt1, DialogResult dlg2, string txt2)
        {
            return new DialogResultText[] { new DialogResultText(dlg1, txt1), new DialogResultText(dlg2, txt2) };
        }
        public static DialogResultText[] GetDialogResultText(DialogResult dlg1, string txt1, DialogResult dlg2, string txt2, DialogResult dlg3, string txt3)
        {
            return new DialogResultText[] { new DialogResultText(dlg1, txt1), new DialogResultText(dlg2, txt2), new DialogResultText(dlg3, txt3) };
        }
        
        public static DialogResultText[] GetOKDialogResultText(string ok)
        {
            return new DialogResultText[] { new DialogResultText(DialogResult.OK, ok)};
        }
        public static DialogResultText[] GetOKCancelDialogResultText(string ok, string cancel)
        {
            return new DialogResultText[] { new DialogResultText(DialogResult.OK, ok),
             new DialogResultText(DialogResult.Cancel, cancel) };
        }
        public static DialogResultText[] GetAbortRetryIgnoreDialogResultText(string abort, string retry, string ignore)
        {
            return new DialogResultText[] { new DialogResultText(DialogResult.Abort, abort), 
                new DialogResultText(DialogResult.Retry, retry),
            new DialogResultText(DialogResult.Ignore, ignore)};
        }
        public static DialogResultText[] GetYesNoCancelDialogResultText(string yes, string no, string cancel)
        {
            return new DialogResultText[] { new DialogResultText(DialogResult.Yes, yes), 
                new DialogResultText(DialogResult.No, no), 
                new DialogResultText(DialogResult.Cancel, cancel) };
        }
        public static DialogResultText[] GetYesNoDialogResultText(string yes, string no)
        {
            return new DialogResultText[] { new DialogResultText(DialogResult.Yes, yes), 
                new DialogResultText(DialogResult.No, no)};
        }
        public static DialogResultText[] GetRetryCancelDialogResultText(string retry, string cancel)
        {
            return new DialogResultText[] { new DialogResultText(DialogResult.Retry, retry),
             new DialogResultText(DialogResult.Cancel, cancel) };
        }

        private static DialogResult[] MessageBoxButtonsToDialogResults(MessageBoxButtons buttons)
        {
            if (!Enum.IsDefined(typeof(MessageBoxButtons), (object)buttons))
            {
                throw new InvalidEnumArgumentException("buttons", (int)buttons, typeof(DialogResult));
            }
            else
            {
                switch (buttons)
                {
                    case MessageBoxButtons.OK:
                        return new DialogResult[1]
            {
              DialogResult.OK
            };
                    case MessageBoxButtons.OKCancel:
                        return new DialogResult[2]
            {
              DialogResult.OK,
              DialogResult.Cancel
            };
                    case MessageBoxButtons.AbortRetryIgnore:
                        return new DialogResult[3]
            {
              DialogResult.Abort,
              DialogResult.Retry,
              DialogResult.Ignore
            };
                    case MessageBoxButtons.YesNoCancel:
                        return new DialogResult[3]
            {
              DialogResult.Yes,
              DialogResult.No,
              DialogResult.Cancel
            };
                    case MessageBoxButtons.YesNo:
                        return new DialogResult[2]
            {
              DialogResult.Yes,
              DialogResult.No
            };
                    case MessageBoxButtons.RetryCancel:
                        return new DialogResult[2]
            {
              DialogResult.Retry,
              DialogResult.Cancel
            };
                    default:
                        throw new ArgumentException("buttons");
                }
            }
        }

        private static Icon MessageBoxIconToIcon(MessageBoxIcon icon)
        {
            if (!Enum.IsDefined(typeof(MessageBoxIcon), (object)icon))
            {
                throw new InvalidEnumArgumentException("icon", (int)icon, typeof(DialogResult));
            }
            else
            {
                switch (icon)
                {
                    case MessageBoxIcon.Question:
                        return SystemIcons.Question;
                    case MessageBoxIcon.Exclamation:
                        return SystemIcons.Exclamation;
                    case MessageBoxIcon.Asterisk:
                        return SystemIcons.Information;
                    case MessageBoxIcon.None:
                        return (Icon)null;
                    case MessageBoxIcon.Hand:
                        return SystemIcons.Error;
                    default:
                        throw new ArgumentException("icon");
                }
            }
        }

        internal delegate DialogResult ShowDxDialogHandler(Form form, string text, string caption, DialogResult[] buttons, MessageBoxIcon icon, DialogResultText[] buttonsText);
       
        public static DialogResult ShowDxDialog(this Form form, string text, string caption,
            MessageBoxButtons buttons, MessageBoxIcon icon, DialogResultText[] buttonsText = null)
        {
            return ShowDxDialog(form, text, caption, MessageBoxButtonsToDialogResults(buttons), icon, buttonsText);
        }

        public static DialogResult ShowDxDialog(this Form form, string text, string caption,
           DialogResult[] buttons, MessageBoxIcon icon, DialogResultText[] buttonsText = null)
        {
            if (form != null && form.InvokeRequired)
            {
                object obj = form.Invoke(new ShowDxDialogHandler(ShowDxDialog), form, text, caption, buttons, icon, buttonsText);
                return DialogResult.None.FromObject(obj);
            }
            PNXtraMessageBoxForm f = new PNXtraMessageBoxForm();
            if (buttonsText != null)
            {
                foreach (var i in buttonsText)
                {
                    if (!f.ButtonsText.ContainsKey(i.DialogResult))
                        f.ButtonsText.Add(i.DialogResult, i.Text);
                }
            }
            DialogResult d = f.ShowMessageBoxDialog(new XtraMessageBoxArgs(form, text, caption, buttons, MessageBoxIconToIcon(icon), 0));
            return d;
        }

        #region Info
        public static DialogResult ShowDxInfoDialog(this Form form, string text, string caption, string btnText = null)
        {
            DialogResultText[] btns = null;
            if (btnText.IsNotNull())
                btns = GetDialogResultText(DialogResult.OK, btnText);

            return ShowDxDialog(form, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Information, btns);
        }

        public static DialogResult ShowDxInfoDialog(this Form form, string text)
        {
            return ShowDxInfoDialog(form, text, Application.ProductName);
        }
        #endregion

        #region Error
        public static DialogResult ShowDxErrorDialog(this Form form, string text, string caption, string btnText = null)
        {
            DialogResultText[] btns = null;
            if (btnText.IsNotNull())
                btns = GetDialogResultText(DialogResult.OK, btnText);
            return ShowDxDialog(form, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Error, btns);
        }

        public static DialogResult ShowDxErrorDialog(this Form form, string text)
        {
            return ShowDxErrorDialog(form, text, Application.ProductName);
        }
        #endregion

        #region Warning
        public static DialogResult ShowDxWarningDialog(this Form form, string text, string caption, string btnText = null)
        {
            DialogResultText[] btns = null;
            if (btnText.IsNotNull())
                btns = GetDialogResultText(DialogResult.OK, btnText);
            return ShowDxDialog(form, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning, btns);
        }

        public static DialogResult ShowDxWarningDialog(this Form form, string text)
        {
            return ShowDxWarningDialog(form, text, Application.ProductName);
        }
        #endregion

        #region Yes No Question
        /// <summary>
        /// Shows dialog with Yes, No buttons
        /// </summary>
        /// <param name="form"></param>
        /// <param name="text">Text on the form</param>
        /// <param name="caption">Forms caption</param>
        /// <param name="buttonsText">Use DxFormExt.GetYesNoDialogResultText() method</param>
        /// <returns></returns>
        public static DialogResult ShowDxYNQuestionDialog(this Form form, string text, string caption, DialogResultText[] buttonsText = null)
        {
            return ShowDxDialog(form, text, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question, buttonsText);
        }
        /// <summary>
        /// Shows dialog with Yes, No buttons
        /// </summary>
        /// <param name="form"></param>
        /// <param name="text">Text on the form</param>
        /// <param name="buttonsText">Use DxFormExt.GetYesNoDialogResultText() method</param>
        /// <returns></returns>
        public static DialogResult ShowDxYNQuestionDialog(this Form form, string text, DialogResultText[] buttonsText = null)
        {
            return ShowDxYNQuestionDialog(form, text, Application.ProductName, buttonsText);
        }
        #endregion

        #region Yes No Cancel Question
        /// <summary>
        /// Shows dialog with Yes No Cancel buttons
        /// </summary>
        /// <param name="form"></param>
        /// <param name="text">Text on the form</param>
        /// <param name="caption">Forms caption</param>
        /// <param name="buttonsText">Use DxFormExt.GetYesNoCancelDialogResultText method</param>
        /// <returns></returns>
        public static DialogResult ShowDxYNCQuestionDialog(this Form form, string text, string caption, DialogResultText[] buttonsText = null)
        {
            return ShowDxDialog(form, text, caption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, buttonsText);
        }
        /// <summary>
        /// Shows dialog with Yes No Cancel buttons
        /// </summary>
        /// <param name="form"></param>
        /// <param name="text">Text on the form</param>
        /// <param name="buttonsText">Use DxFormExt.GetYesNoCancelDialogResultText method</param>
        /// <returns></returns>
        public static DialogResult ShowDxYNCQuestionDialog(this Form form, string text, DialogResultText[] buttonsText = null)
        {
            return ShowDxYNCQuestionDialog(form, text, Application.ProductName, buttonsText);
        }
        #endregion

        #region Language
        internal delegate DialogResult ShowDxLngDialogHandler(Form form, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, params object[] args);
        
        public static DialogResult ShowDxLngDialog(this Form form, string text, string caption,
            MessageBoxButtons buttons, MessageBoxIcon icon, params object[] args)
        {
            if (form.InvokeRequired)
            {
                object obj = form.Invoke(new ShowDxLngDialogHandler(ShowDxLngDialog), form, text, caption, buttons, icon);
                return DialogResult.None.FromObject(obj);
            }
            return XtraMessageBox.Show(form, ProgNetLanguage.sGetString(text, args), caption, buttons, icon);
        }

        #region Info
        public static DialogResult ShowDxLngInfoDialog(this Form form, string text, string caption)
        {
            return ShowDxLngDialog(form, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        public static DialogResult ShowDxLngInfoDialog(this Form form, string text)
        {
            return ShowDxLngInfoDialog(form, text, Application.ProductName);
        }
        #endregion

        #region Error
        public static DialogResult ShowDxLngErrorDialog(this Form form, string text, string caption, params object[] args)
        {
            return ShowDxLngDialog(form, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Error, args);
        }

        public static DialogResult ShowDxLngErrorDialog(this Form form, string text)
        {
            return ShowDxLngErrorDialog(form, text, Application.ProductName);
        }
        public static DialogResult ShowDxLngErrorDialog(this Form form, string text, object[] args)
        {
            return ShowDxLngErrorDialog(form, text, Application.ProductName, args);
        }
        #endregion

        #region Warning
        public static DialogResult ShowDxLngWarningDialog(this Form form, string text, string caption, params object[] args)
        {
            return ShowDxLngDialog(form, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning, args);
        }

        public static DialogResult ShowDxLngWarningDialog(this Form form, string text)
        {
            return ShowDxLngWarningDialog(form, text, Application.ProductName);
        }
        public static DialogResult ShowDxLngWarningDialog(this Form form, string text, object[] args)
        {
            return ShowDxLngWarningDialog(form, text, Application.ProductName, args);
        }
        #endregion

        #region Yes No Question
        public static DialogResult ShowDxLngYNQuestionDialog(this Form form, string text, string caption, params object[] args)
        {
            return ShowDxLngDialog(form, text, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question, args);
        }

        public static DialogResult ShowDxLngYNQuestionDialog(this Form form, string text)
        {
            return ShowDxLngYNQuestionDialog(form, text, Application.ProductName);
        }
        public static DialogResult ShowDxLngYNQuestionDialog(this Form form, string text, object[] args)
        {
            return ShowDxLngYNQuestionDialog(form, text, Application.ProductName, args);
        }
        #endregion

        #region Yes No Cancel Question
        public static DialogResult ShowDxLngYNCQuestionDialog(this Form form, string text, string caption, params object[] args)
        {
            return ShowDxLngDialog(form, text, caption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, args);
        }

        public static DialogResult ShowDxLngYNCQuestionDialog(this Form form, string text)
        {
            return ShowDxLngYNCQuestionDialog(form, text, Application.ProductName);
        }
        public static DialogResult ShowDxLngYNCQuestionDialog(this Form form, string text, object[] args)
        {
            return ShowDxLngYNCQuestionDialog(form, text, Application.ProductName, args);
        }
        #endregion
        #endregion

        #region layout
        public static string GetLayoutXml(this Form form, FormLayoutSettings settings = null)
        {
            string layoutXml = "";
            try
            {
                XmlDocument doc = new XmlDocument();
                XmlElement n = doc.CreateElement(form.Name);
                n.AppendAttribute("Left", form.Left);
                n.AppendAttribute("Top", form.Top);
                n.AppendAttribute("Width", form.Width);
                n.AppendAttribute("Height", form.Height);
                n.AppendAttribute("WindowState", form.WindowState);

                n.AppendAttribute("SaveSize", (settings != null ? settings.SaveSize : true));
                n.AppendAttribute("SavePosition", (settings != null ? settings.SavePosition : true));
                
                doc.AppendChild(n);
                StringWriter strWriter = new StringWriter();
                XmlTextWriter xmlWriter = new XmlTextWriter(strWriter);
                xmlWriter.Formatting = Formatting.Indented;
                doc.WriteTo(xmlWriter);
                layoutXml = strWriter.GetStringBuilder().ToString();
            }
            catch (Exception ex)
            {
                ex.LogInternal();
            }
            return layoutXml;
        }
        public static void SetLayoutXml(this Form form, string layout, FormLayoutSettings settings = null)
        {
            XmlDocument doc = new XmlDocument();
            try
            {
                doc.LoadXml(layout);
                if (doc.ChildNodes.Count > 0)
                {
                    XmlNode n = doc.ChildNodes[0];
                    if (n.Attributes != null)
                    {
                        if (settings != null)
                        {
                            if (n.Attributes["SaveSize"] != null)
                                settings.SaveSize = n.GetAttributeValue("SaveSize").AsBool();
                            if (n.Attributes["SavePosition"] != null)
                                settings.SavePosition = n.GetAttributeValue("SavePosition").AsBool();
                        }
                        
                        if (settings == null || settings.SaveSize)
                        {
                            if (n.Attributes["Width"] != null)
                                form.Width = n.GetAttributeValue("Width").AsInt();
                            if (n.Attributes["Height"] != null)
                                form.Height = n.GetAttributeValue("Height").AsInt();
                            if (n.Attributes["WindowState"] != null)
                                form.WindowState = n.GetAttributeValue("WindowState").AsEnum<FormWindowState>(form.WindowState);
                        }
                        if (settings == null || settings.SavePosition)
                        {
                            form.StartPosition = FormStartPosition.Manual;

                            if (n.Attributes["Left"] != null)
                                form.Left = n.GetAttributeValue("Left").AsInt();
                            if (n.Attributes["Top"] != null)
                                form.Top = n.GetAttributeValue("Top").AsInt();
                        }
                        else
                        {
                            if (form.StartPosition == FormStartPosition.CenterParent)
                                form.RunMethod("CenterToParent");
                            else if (form.StartPosition == FormStartPosition.CenterScreen)
                                form.RunMethod("CenterToScreen");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ex.LogInternal();
            }
        }
        #endregion

        public static void FinishEditBindings(this ContainerControl control)
        {
            control.SelectNextControl(control.ActiveControl, true, true, true, true);
            control.SelectNextControl(control.ActiveControl, false, true, true, true);
            if (control.ActiveControl != null)
            {
                if (control.ActiveControl is ContainerControl)
                {
                    (control.ActiveControl as ContainerControl).FinishEditBindings();
                }
                if (control.ActiveControl is GridControl)
                {
                    if ((control.ActiveControl as GridControl).FocusedView != null)
                    {
                        (control.ActiveControl as GridControl).FocusedView.CloseEditor();
                        (control.ActiveControl as GridControl).FocusedView.UpdateCurrentRow();
                    }
                }
                if (control.ActiveControl is PopupBaseEdit)
                {
                    (control.ActiveControl as PopupBaseEdit).ClosePopup();
                }
                if (control.ActiveControl.DataBindings.Count > 0)
                {
                    foreach (Binding b in control.ActiveControl.DataBindings)
                        b.WriteValue();
                }
            }
            
        }

        private static Dictionary<XtraTabbedMdiManager, int> mgrs = new Dictionary<XtraTabbedMdiManager, int>();
        private static Dictionary<Form, XtraTabbedMdiManager> forms = new Dictionary<Form, XtraTabbedMdiManager>();

        public static void SetMinTabSize(this DevExpress.XtraTabbedMdi.XtraTabbedMdiManager manager, int minWidth)
        {
            manager.PageAdded -= new DevExpress.XtraTabbedMdi.MdiTabPageEventHandler(manager_PageAdded);
            if (minWidth > 0)
                manager.PageAdded += new DevExpress.XtraTabbedMdi.MdiTabPageEventHandler(manager_PageAdded);
            if (!mgrs.ContainsKey(manager))
                mgrs.Add(manager, minWidth);
            else
                mgrs[manager] = minWidth;

            foreach (XtraMdiTabPage p in manager.Pages)
                manager.SetPageSize(p, minWidth);
        }

        static void manager_PageAdded(object sender, DevExpress.XtraTabbedMdi.MdiTabPageEventArgs e)
        {
            int minSize = -1;
            XtraTabbedMdiManager m = sender as XtraTabbedMdiManager;
            if (m != null)
            {
                minSize = mgrs[m];
                m.SetPageSize(e.Page, minSize);
            }
            e.Page.MdiChild.TextChanged += new EventHandler(MdiChild_TextChanged);
            e.Page.MdiChild.FormClosed += new FormClosedEventHandler(MdiChild_FormClosed);
            forms.Add(e.Page.MdiChild, m);
        }

        static void MdiChild_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                forms.Remove(sender as Form);
            }
            catch { }
        }

        static void MdiChild_TextChanged(object sender, EventArgs e)
        {
            Form f = sender as Form;
            try
            {
                XtraTabbedMdiManager m = forms[f];
                SetPageSize(m, m.Pages[f], mgrs[m]);
            }
            catch { }
        }

        public static void SetPageSize(this XtraTabbedMdiManager m, XtraMdiTabPage page,  int minSize)
        {
            string text = page.MdiChild.Text.Trim();
            if (minSize > 0)
            {
                while (text.Mesure(m.Appearance.Font).Width < minSize)
                    text += " ";
            }
            page.Text = text;
        }

        #region Serialize/Deserialize Values
        /// <summary>
        /// Saves controls values to xml
        /// </summary>
        /// <param name="parent">Parent control</param>
        /// <param name="edits">list of controls</param>
        /// <param name="fullSerialize">if false only controls that have not null EditValue will be saved</param>
        /// <returns></returns>
        public static string SerializeValues(this Control parent, List<BaseEdit> edits, bool fullSerialize = true)
        {
            string xml = string.Empty;
            try
            {
                XmlDocument d = new XmlDocument();
                foreach (var e in edits)
                {
                    if (fullSerialize || e.EditValue.IsNotNull())
                        AddElement(parent, d, e);
                }
                xml = d.ToFormatedString();
            }
            catch { }
            return xml;
        }
        /// <summary>
        /// Saves controls values to xml
        /// </summary>
        /// <param name="parent">Parent control</param>
        /// <param name="fullSerialize">if false only controls that have not null EditValue will be saved</param>
        /// <param name="onlyParentControls">if true, children of child controls will be skipped</param>
        /// <returns></returns>
        public static string SerializeValues(this Control parent, bool fullSerialize = true, bool onlyParentControls = false)
        {
            string xml = string.Empty;
            try
            {
                XmlDocument d = new XmlDocument();
                SerializeValues(parent, parent, d, fullSerialize, onlyParentControls);
                xml = d.ToFormatedString();
            }
            catch { }
            return xml;
        }

        private static void SerializeValues(Control parent, Control c, XmlDocument d, bool fullSerialize, bool onlyParentControls)
        {
            foreach (Control ct in c.Controls)
            {
                if (ct is BaseEdit)
                {
                    if (fullSerialize || ((BaseEdit)ct).EditValue.IsNotNull())
                    {
                        AddElement(parent, d, (BaseEdit)ct);
                    }
                }
                else if(!onlyParentControls)
                {
                    SerializeValues(parent, ct, d, fullSerialize, onlyParentControls);
                }
            }
        }
        private static void AddElement(Control mainParent, XmlDocument d, BaseEdit edit)
        {
            Control parent = edit.Parent;
            List<Control> parents = new List<Control>();
            while (parent != null && parent != mainParent)
            {
                parents.Add(parent);
                parent = parent.Parent;
            }
            XmlNode pNode = d.AppendChildElement(mainParent.Name);
            parents.Reverse();

            foreach (var p in parents)
            {
                pNode = pNode.AppendChildElement(p.Name);
            }
            pNode = pNode.AppendChildElement(edit.Name);
            pNode.AppendAttribute("EditValue", edit.EditValue);
            if (edit.EditValue.IsNotNull())
                pNode.AppendAttribute("Type", edit.EditValue.GetType());
        }

        /// <summary>
        /// Reads controls values from xml
        /// </summary>
        /// <param name="parent">Parent control</param>
        /// <param name="xml">xml</param>
        /// <param name="edits">list of controls</param>
        /// <param name="fullDeserialize">if true - if control is not presend in xml EditValue will be set to null
        /// <para>else control will be skipped</para></param>
        public static void DeserializeValues(this Control parent, string xml, List<BaseEdit> edits, bool fullDeserialize = true)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                
                foreach (var e in edits)
                {
                    SetControlValue(e, GetElement(parent, doc, e), fullDeserialize);
                }
            }
            catch { }
        }
        /// <summary>
        /// Reads controls values from xml
        /// </summary>
        /// <param name="parent">Parent control</param>
        /// <param name="xml">xml</param>
        /// <param name="fullDeserialize">if true - if control is not presend in xml EditValue will be set to null
        /// <para>else control will be skipped</para></param>
        /// <param name="onlyParentControls">if true, children of child controls will be skipped</param>
        public static void DeserializeValues(this Control parent, string xml, bool fullDeserialize = true, bool onlyParentControls = false)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            XmlElement el = doc.SelectSingleElement(parent.Name);
            DesiarializeControlValues(parent, doc, fullDeserialize, onlyParentControls);
        }

        private static XmlElement GetElement(Control parent, XmlDocument doc, BaseEdit edit)
        {
            List<Control> parents = new List<Control>();
            Control p = edit.Parent;
            XmlElement pNode = doc.SelectSingleElement(parent.Name);
            while (p != null && p != parent)
            {
                parents.Add(p);
                p = p.Parent;
            }
            parents.Reverse();
            foreach (var pa in parents)
            {
                if (pNode != null)
                    pNode = pNode.SelectSingleElement(pa.Name);
                else
                    break;
            }
            if(pNode!=null)
                pNode = pNode.SelectSingleElement(edit.Name);
            return pNode;
        }
        private static void DesiarializeControlValues(Control c, XmlNode parentNode, bool fullDeserialize, bool onlyParentControls)
        {
            XmlElement el = null;
            foreach (Control ct in c.Controls)
            {
                if (parentNode != null)
                    el = parentNode.SelectSingleElement(ct.Name);
                if (ct is BaseEdit)
                {
                    SetControlValue((BaseEdit)ct, el, fullDeserialize);
                }
                else if(!onlyParentControls)
                {
                    DesiarializeControlValues(ct, el, fullDeserialize, onlyParentControls);
                }
            }
        }
        private static void SetControlValue(BaseEdit edit, XmlElement el, bool fullDeserialize)
        {
            object realVal = null;
            if (el != null)
            {
                string val = el.GetAttributeValue("EditValue");
                string type = el.GetAttributeValue("Type");

                if (val.IsNotNull())
                {
                    realVal = val;
                    if (type.IsNotNull())
                    {
                        try
                        {
                            Type t = Type.GetType(type);
                            if (t != null)
                            {
                                realVal = val.ChangeType(t);
                            }
                        }
                        catch { }
                    }
                }
                edit.EditValue = realVal;
            }
            else if (fullDeserialize)
            {
                edit.EditValue = null;
            }
        }
        #endregion
    }
}
